package com.coderg.gmall.cart.MQ;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.coderg.gmall.cart.service.CartService;
import com.coderg.gmall.cart.util.GmallThreadLocalUtils;
import com.coderg.gmall.model.cart.CartInfo;
import com.coderg.gmall.rabbitMq.constant.RabbitConst;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.List;

/**
 * @Description 通用的一个消息消费类
 * @Author CoderG
 * @Date 2025/6/13 22:29
 **/
@Component
@Slf4j
public class MessageConsumer {

    @Autowired
    CartService cartService;

    /**
     * 最大重试次数
     */
    private static final int MAX_RETRY_COUNT = 1;
    /**
     * 消费失败后延迟投递时间 单位毫秒
     */
    private static final int DELAY_TIME = 1000;

    @RabbitListener(queues = {RabbitConst.CART_QUEUE})
    public void handleMessage(Message message, Channel channel) throws IOException {
        try {
            // 1. 尝试处理消息
            processMessage(message);
            //获取消息编号
            long deliveryTag = message.getMessageProperties().getDeliveryTag();

            // 2. 处理成功，手动确认
            channel.basicAck(deliveryTag, false);

        } catch (Exception e) {
            log.error(e.getMessage());
            // 3. 处理失败逻辑
            handleFailedMessage(message, channel);
        }
    }

    private void processMessage(Message message) {
        // 实际业务处理逻辑
        String jsonStr = new String(message.getBody());
        if (StringUtils.isEmpty(jsonStr)) {
            return;
        }
        String username = jsonStr.split("--")[0];
        String cartJson = jsonStr.split("--")[1];
        if (StringUtils.isEmpty(username)) {
            return;
        }
        //将用户名设置到缓存
        GmallThreadLocalUtils.setUserName(username);
        if ("[]".equals(cartJson)){
            //集合为空 不用合并 直接查数据库 放入缓存
            //查询购物车 放入缓存
            cartService.getCarts();
        }else {
            List<CartInfo> cartList = JSON.parseObject(cartJson,
                    new TypeReference<List<CartInfo>>() {
                    });
            //合并购物车
            cartService.combineCart(cartList);

            //查询购物车，将它准备到缓存
            cartService.getCarts();
        }


    }

    private void handleFailedMessage(Message message, Channel channel) throws IOException {
        //获取消息编号
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        //是否是重新投递的消息
        Boolean redelivered = message.getMessageProperties().getRedelivered();

        if (redelivered) {
            // 不是 放回原队列
            channel.basicReject(deliveryTag, true);

        } else {
            // 可选：将失败消息转移到死信队列
            // rabbitTemplate.convertAndSend("dlx.exchange", "dlx.routing", message);
            // 确认已消费（不再重新投递）
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            // 记录到数据库或日志系统
            logFailedMessage(message);
        }
    }

    private void logFailedMessage(Message message) {
        // 实现失败消息的持久化记录
        log.error("消息投递失败: " + new String(message.getBody()));
    }
}
